/*
 * 
 */
package com.yeqiangwei.commons.image;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.yeqiangwei.commons.io.FileHelper;
import com.yeqiangwei.commons.util.ArithHelper;
import com.yeqiangwei.commons.util.TypeChange;

import magick.ImageInfo;
import magick.MagickException;
import magick.MagickImage;

public class ImageMagickHanlder {
	
	private File imageFile;
	private ImageInfo imageInfo;
	private MagickImage magickImage;
	
	public ImageMagickHanlder(File imageFile){
		this.imageFile = imageFile;
		this.init();
	}
	
	public ImageMagickHanlder(String imagePath){
		this.imageFile = new File(imagePath);
		this.init();
	}
	
	private void init(){
		try {
			System.setProperty("jmagick.systemclassloader", "no");
			imageInfo = new ImageInfo(imageFile.getAbsolutePath());
			magickImage = new MagickImage(imageInfo);
		} catch (MagickException e) {
			log.error(e);
		}
	}
	
	/**
	 * 设置成正方形
	 * @param outputPath
	 * @return
	 */
	public boolean setSquare(String outputPath) {
		if(imageInfo == null){
			// System.out.println("[EEE] Failed to initialize ImageInfo");
			log.error("[EEE] Failed to initialize ImageInfo");
			return false;
		}
		if(magickImage == null){
			// System.out.println("[EEE] Failed to initialize MagickImage");
			log.error("[EEE] Failed to initialize MagickImage");
			return false;
		}
		try {
			Dimension dim = magickImage.getDimension();
			double w = dim.getWidth();
			double h = dim.getHeight();
			if (w != h) {
				Rectangle rect = null;
				if (w > h) {
					// 高宽差
					double i = w - h;
					rect = new Rectangle(TypeChange.doubleToInt(i / 2)
							, 0
							, TypeChange.doubleToInt(h)
							, TypeChange.doubleToInt(h));
				} else if (w < h) {
					rect = new Rectangle(0
							, 0
							, TypeChange.doubleToInt(w)
							, TypeChange.doubleToInt(w));
				}
				MagickImage cropped = magickImage.cropImage(rect);
				cropped.setFileName(imageFile.getAbsolutePath());
				cropped.writeImage(imageInfo);
			} else {
				FileHelper.copyFile(imageFile.getAbsolutePath(), outputPath);
			}
		} catch (Exception e) {
			log.error(e);
			System.out.println(e);
			return false;
		}
		return true;
	}
	
	/**
	 * 按指定宽高重设尺寸 
	 * @param outputPath
	 * @param width
	 * @param height
	 * @return
	 */
	public boolean resize(String outputPath, int width, int height) {
		if(log.isDebugEnabled()){
			log.debug("...... #resize(...) npath: " + outputPath);
		}
		try {
			MagickImage scaled = magickImage.scaleImage(width, height);
			if(scaled == null && log.isDebugEnabled()){
				log.error("...... MagickImage is null");
			}
			// 小图片文件的大小
			scaled.setFileName(outputPath);
			return scaled.writeImage(imageInfo);
		} catch (MagickException e) {
			log.error(e.toString());
		}
		return false;
	}
	
	/**
	 * 按坐标切割
	 */
	public boolean incise(String newfilepath, int w, int h,
			int x, int y, int x_w, int y_h) 
	{
		try {
			Rectangle rect = new Rectangle(x, y, w, h);
			MagickImage cropped = magickImage.cropImage(rect);
			cropped.setFileName(newfilepath);
			cropped.writeImage(imageInfo);
			return true;
		} catch (MagickException e) {
			log.error(e.toString());
		}
		return false;
	}
	
	/**
	 * 切割图片坐标 y = 0 , x 自动计算中间部分
	 * 
	 * @param path
	 * @param outputPath
	 * @param w
	 * @param h
	 * @return
	 */
	public boolean inciseTopAndCenter(String outputPath, int w, int h) {
		int x = 0;
		int y = 0;
		try {
			Dimension dim = magickImage.getDimension();
			int ow = TypeChange.doubleToInt(dim.getWidth());
			int oh = TypeChange.doubleToInt(dim.getHeight());
			x = (ow - w) / 2;
			if (x < 0) {
				x = 0;
			}
			ow = ow * (w / (w + h));
			oh = oh * (h / (w + h));
			Rectangle rect = new Rectangle(x, y, ow, oh);
			MagickImage cropped = magickImage.cropImage(rect);
			cropped.setFileName(outputPath);
			cropped.writeImage(imageInfo);
			/* 先切割成和指定高宽比一样形状的图片 */
			/* 然后再按指定的高宽切割图片 */
			ImageInfo ninfo = new ImageInfo(outputPath);
			MagickImage nimage = new MagickImage(imageInfo);
			Rectangle nrect = new Rectangle(0, 0, w, h);
			MagickImage ncropped = nimage.cropImage(nrect);
			ncropped.setFileName(outputPath);
			ncropped.writeImage(ninfo);
			return true;
		} catch (MagickException e) {
			log.error(e);
		}
		return false;
	}
	
	
	/**
	 * 成比例缩放图片
	 */
	public boolean scaled(String outputPath, int w, int h) {
		try {
			Dimension dim = magickImage.getDimension();
			double ow = dim.getWidth();
			double oh = dim.getHeight();
			if(w == 0 && h ==0){
				/* 如果都等于0则不执行任何操作 */
			}
			else if(w > 0 && h > 0){
				return this.resize(outputPath, w, h);
			}
			else if(h == 0){
				double d = ArithHelper.div(w, ow); /* 指定尺寸/源尺寸 */
				h = TypeChange.doubleToInt(ArithHelper.mul(oh, d));
			}
			else if(w == 0){
				double d = ArithHelper.div(h, oh); /* 指定尺寸/源尺寸 */
				w = TypeChange.doubleToInt(ArithHelper.mul(ow, d));
			}
			if(w <= 0){
				w = TypeChange.doubleToInt(ow);
			}
			if(h <= 0){
				w = TypeChange.doubleToInt(oh);
			}
			return this.resize(outputPath, w, h);
		} catch (MagickException e) {
			log.error(e.toString());
		}
		return false;
	}
	
	private static final Log log = LogFactory.getLog(ImageMagickHanlder.class);

	public ImageInfo getImageInfo() {
		return imageInfo;
	}

	public MagickImage getMagickImage() {
		return magickImage;
	}
	
	public Dimension getDimension(){
		if(magickImage == null){
			return null;
		} else {
			try {
				return magickImage.getDimension();
			} catch (MagickException e) {
				log.error(e);
				return null;
			}
		}
	}
}
